import tkinter as tk
from tkinter.constants import S
import tkinter.ttk as ttk
from typing import overload
# import win32api,win32con
import random as rd
import math

from tktree import DrawHeap

INF = 999999
class DrawGraph(object):
	def __init__(self, graph):
		self.graph = graph
		self.root = tk.Tk()

		self.step = tk.IntVar(master = self.root, value = 0)

		self.fmCanvas = tk.Frame(self.root)
		self.fmVerBar = tk.Frame(self.fmCanvas)
		self.fmHorBar = tk.Frame(self.fmCanvas)
		self.fmForButtons = tk.Frame(self.root)

		self.fmForButtons.pack(side = 'top', fill = 'both', expand = True)
		self.fmCanvas.pack(side = 'top', fill = 'both', expand = True)
		self.fmVerBar.pack(side = 'right', fill = 'both', expand = False)
		self.fmHorBar.pack(side = 'bottom', fill = 'both', expand = False)

		self.bt1 = tk.Button(self.fmForButtons, text = '   next   ', command = lambda: self.step.set(self.step.get()+1))
		self.bt2 = tk.Button(self.fmForButtons, text = 'button-2')
		self.bt1.pack(side = 'left')
		self.bt2.pack(side = 'left')
		
		# cx = win32api.GetSystemMetrics(win32con.SM_CXSCREEN)
		# cy = win32api.GetSystemMetrics(win32con.SM_CYSCREEN)
		cx, cy = 1440, 900

		self.baseSize = 25 * cx/1440
		self.zoom = 2 * cx/1440
		self.root.geometry('%dx%d+%d+%d' %(cx*self.zoom*0.2, cy*self.zoom*0.2,cx*0.4, cy*0.5))

		self._drawCanvas()
		self._drawVerticeAndEdges()
		self.bt1.waitvar(self.step)

	def _drawCanvas(self):
		self.offset = self.baseSize // 1.5
		V, E = self.graph.V, self.graph.E
		n = len(V)
		self.canvasWidth = self.canvasHeight = n * self.baseSize * self.zoom
		self.cv = tk.Canvas(self.fmCanvas, width = self.canvasWidth, height = self.canvasHeight, \
							borderwidth = 3, relief = 'ridge')
		self.cv.pack(side = 'left', fill = 'both', expand = True)

		self.verBar = tk.Scrollbar(self.fmVerBar, width = 20)
		self.verBar.pack(side = 'right', fill = 'both', expand = False)
		self.horBar = tk.Scrollbar(self.fmHorBar, orient = 'horizontal', width = 20)
		self.horBar.pack(side = 'bottom', fill = 'both', expand = False)
		self.horBar.config(command = self.cv.xview)
		self.verBar.config(command = self.cv.yview)
		self.cv.config(yscrollcommand = self.verBar.set, xscrollcommand = self.horBar.set, 
					scrollregion = (-100, -100, self.canvasWidth, self.canvasHeight))

	def _drawVerticeAndEdges(self, **kw):
		V, E = self.graph.V, self.graph.E
		n = len(V)
		grid = self.baseSize * self.zoom
		start = grid//2
		hbs = self.baseSize / 2
		i = 0
		for v in V:
			v.drawXY = i * grid + start, i % 3 * grid + start
			v.drawRect = ((v.drawXY[0] - hbs, v.drawXY[1] - hbs), (v.drawXY[0] + hbs, v.drawXY[1] + hbs))
			i += 1

		#draw edges:
		for n, e in enumerate(E):
			if e[0].ID > e[1].ID:
				v1, v2 = e[1], e[0]
			else:
				v1, v2 = e[0], e[1]
			overlap = True
			while overlap:
				overlap = False
				for v3 in V:
					if v3 in e:
						pass
					elif self._dist(v1,v2,v3) < hbs:
						overlap = True
						v2.drawXY = v2.drawXY[0] + grid * 0.5 * pow(-1,n), v2.drawXY[1]
						v2.drawRect = ((v2.drawXY[0] - hbs, v2.drawXY[1] - hbs), (v2.drawXY[0] + hbs, v2.drawXY[1] + hbs))
						break
		for e in E:
			(x1, y1), (x2, y2) = e[0].drawXY, e[1].drawXY
			if self.graph.directG == True:
				ar = 'last'
			else: ar = 'none'
			self.cv.create_line(x1, y1, x2, y2, width=E[e].thickness, fill=E[e].color, tag='edge', arrow= ar, \
								arrowshape=(25, 30, 3))
			if E[e].w != INF:
				x, y = (x1 + x2)/2 , (y1 + y2)/2 
				if y1 != y2:
					k = (-(x1-x2)/(y1-y2))
					sin = k/(pow((1+k*k),0.5))
					cos = 1/(pow((1+k*k),0.5))
					dx = hbs * 0.4 * cos
					dy = hbs * 0.4 * sin
					if k < 0:
						dx, dy = -dx, -dy
				else:
					dx, dy = 0, hbs * 0.4
				if self.graph.directG == False:
					self.cv.create_text(x+dx, y+dy, text=str(E[e].w), angle=0, tag='weight')
				else:
					if x1 > x2:
						self.cv.create_text(x+dx, y+dy, text=str(E[e].w), angle=0, tag='weight')
					else:
						self.cv.create_text(x-dx, y-dy, text=str(E[e].w), angle=0, tag='weight')

		#draw vertices
		for v in V:
			(x1, y1), (x2, y2) = v.drawRect
			self.cv.create_oval(x1, y1, x2, y2, fill = v.color, tag = 'vertice')
			self.cv.create_text(v.drawXY[0], v.drawXY[1], text = str(v.content), tag = 'vertice')
		self.cv.lift('weight')

	def _dist(self, p1, p2, p3):
		x1, y1, x2, y2, x3, y3 = p1.drawXY[0], p1.drawXY[1], p2.drawXY[0], p2.drawXY[1], p3.drawXY[0], p3.drawXY[1]
		dy, dx = y2-y1, x2-x1
		C = y1*dx - x1*dy
		d = abs(dy*x3 - dx*y3 + C)/pow((dx*dx + dy*dy), 0.5)
		return d

	def _redraw(self):
		self.root.destroy()
		self.__init__(self.graph)









